#include <pthread.h>
#include <iostream>
#include <string>
#include <functional>
#include"log.hpp"

using namespace LogModule;
std::uint32_t cnt = 1;
using threadfunc_t = std::function<void()>;
enum class TSTATUS
{
    THREAD_NEW,
    THREAD_RUNNING,
    THREAD_STOP
};
class Thread
{
    static void* run(void* arg)
    {
        Thread* self=static_cast<Thread*>(arg);
        pthread_setname_np(pthread_self(), self->name.c_str());
        if(self->status==TSTATUS::THREAD_NEW)
        {
            //设置线程状态：
            self->status=TSTATUS::THREAD_RUNNING;
        }
        //如果设置成了分离那就调用分离函数
        if(!(self->joined))
        {
            pthread_detach(pthread_self());
        }
        //调用相关函数：
        self->func();
        return nullptr;
    }
public:
    void Setname()
    {
        this->name="thread-"+std::to_string(cnt);
        cnt++;
    }
    std::string Getname()
    {
        return name;
    }
    Thread(threadfunc_t rout)
        : func(rout), status(TSTATUS::THREAD_NEW), joined(true)
    {
            Setname();
    }
    bool Start()
    {
        //一个线程不能连续运行两次
        //如果已经是运行状态就返回
        if(status==TSTATUS::THREAD_RUNNING)
        {
            LOG(LogLevel::ERROR)<<"线程已处于运行状态";
            return true;
        }
        //静态成员函数访问不了非静态成员函数所以传this指针
        int n=pthread_create(&tid,NULL,run,this);
        if(n!=0)
        {
            std::cout<<"thread_creat fail!"<<std::endl;
            return false;
        }
        return true;
    }
    void EnableDetach()
    {
        if(status==TSTATUS::THREAD_NEW)
        joined=false;
    }
    void EnableJoined()
    {
        if(status==TSTATUS::THREAD_NEW)
        joined=true;
    }
    bool join()
    {
        if(joined)
        {
            int n=pthread_join(tid,nullptr);
            if(n>0)
            return true;
            else
            return false;
        }
        return false;
    }
private:
    // 线程名字：
    std::string name;
    // 线程id
    pthread_t tid;
    // 线程状态：
    TSTATUS status;
    // joinable
    bool joined;
    // 线程关联的函数：
    threadfunc_t func;
};